'''Methods for handling template rendering.
'''
import cherrypy
from genshi.template import Context, TemplateLoader

loaders = {}

def get_loader(name, path=None):
    '''Creates or gets an existing template loader with the specified name.'''
    if name not in loaders:
        if path == None:
            return None
        loader = TemplateLoader(path, auto_reload=True)
        loaders[name] = loader
    return loaders[name]

def url():
    '''Determines the base url of the application.'''
    url = cherrypy.url()
    return url.replace(cherrypy.request.path_info[1:], '')

def expose(template):
    def decorate(func):
        def wrapper(*args, **kw):
            
            result = func(*args, **kw)
            
            loader = get_loader(args[0].__class__.__name__)
            
            if not loader:
                raise Exception("Loader not initialized. You must call get_loader() with a path before using.")
            
            ctx = Context(url=url, cherrypy=cherrypy)
            ctx.update(result)
            
            return [loader.load(template).generate(ctx).render('xhtml', encoding='ascii')]
        wrapper.__name__ = func.__name__
        wrapper.__dict__ = func.__dict__
        wrapper.__doc__ = func.__doc__
        if hasattr(func, 'func'):
            wrapper.func = func.func
        else:
            wrapper.func = func
        wrapper.exposed = True
        
        return wrapper
    return decorate